package notify

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

// WxPusher 表示WxPusher的结构体
type WxPusher struct {
	AppToken string
	client   *http.Client
	baseURL  string
}

// NewWxPusher 创建一个新的WxPusher实例
//
// appToken 是WxPusher平台分配的应用token
//
// 使用示例:
//
//	pusher := NewWxPusher("AT_xxxxx")
//	msg := WxPusherMessage{
//		Content:     "测试消息",
//		ContentType: 1,
//		Uids:       []string{"UID_xxxxx"},
//	}
//	result, err := pusher.Send(&msg)
//	if err != nil {
//		logger.Log.Error("发送失败: %v", err)
//		return
//	}
//	logger.Log.Success("发送成功! 消息ID: %d", result.Data[0].MessageId)
func NewWxPusher(appToken string) *WxPusher {
	return &WxPusher{
		AppToken: appToken,
		client:   &http.Client{},
		baseURL:  "https://wxpusher.zjiecode.com/api/send/message",
	}
}

// WxPusherMessage 表示要发送的消息结构体
type WxPusherMessage struct {
	AppToken      string   `json:"appToken"`            // 应用的token,必传
	Content       string   `json:"content"`             // 消息内容,必传
	Summary       string   `json:"summary,omitempty"`   // 消息摘要,显示在微信聊天页面或者模版消息卡片上,限制长度20,可选,默认截取content前面内容
	ContentType   int      `json:"contentType"`         // 内容类型:1表示文字,2表示html(推荐),3表示markdown
	TopicIds      []int    `json:"topicIds,omitempty"`  // 发送目标主题ID数组,用于群发,使用uids单发时可不传
	Uids          []string `json:"uids,omitempty"`      // 发送目标用户ID数组,可与topicIds同时使用或单独使用
	Url           string   `json:"url,omitempty"`       // 原文链接,可选参数
	VerifyPay     bool     `json:"verifyPay,omitempty"` // 是否只推送给付费订阅用户(即将废弃,建议使用verifyPayType)
	VerifyPayType int      `json:"verifyPayType"`       // 是否验证订阅时间,0:不验证,1:只发送给付费用户,2:只发送给未订阅或订阅过期用户
}

// WxPusherResult 表示WxPusher的响应结构体
type WxPusherResult struct {
	Code    int    `json:"code"`
	Msg     string `json:"msg"`
	Success bool   `json:"success"`
	Data    []struct {
		Uid              string `json:"uid"`
		TopicId          *int   `json:"topicId"`
		MessageId        int    `json:"messageId"`
		MessageContentId int    `json:"messageContentId"`
		SendRecordId     int    `json:"sendRecordId"`
		Code             int    `json:"code"`
		Status           string `json:"status"`
	} `json:"data"`
}

// Send 发送消息
func (w *WxPusher) Send(msg *WxPusherMessage) (*WxPusherResult, error) {
	msg.AppToken = w.AppToken

	jsonData, err := json.Marshal(msg)
	if err != nil {
		return nil, fmt.Errorf("序列化消息失败: %v", err)
	}

	resp, err := w.client.Post(
		w.baseURL,
		"application/json",
		bytes.NewBuffer(jsonData),
	)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("请求失败,状态码: %d", resp.StatusCode)
	}

	var result WxPusherResult
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	if result.Code != 1000 {
		return nil, fmt.Errorf("发送失败: %s", result.Msg)
	}

	return &result, nil
}

func GetWxPusherHtmlTemplateMessage(htmlTemplate string) WxPusherMessage {
	return WxPusherMessage{
		ContentType: 2,
		Content:     htmlTemplate,
	}
}

// ExampleSendMessage 展示如何使用WxPusher发送消息的示例
//
// 首先创建一个WxPusher实例,需要传入有效的AppToken
// 然后构造HTML格式的消息内容
// 设置接收消息的用户UID
// 最后调用Send方法发送消息
//
// 完整示例:
//
//	pusher := NewWxPusher("AT_xxxxx")
//	msg := GetWxPusherHtmlTemplateMessage(`
//		<h1>测试通知</h1>
//		<p>这是一条测试消息</p>
//	`)
//	msg.Uids = []string{"UID_xxxxx"}
//	result, err := pusher.Send(&msg)
//	if err != nil {
//		fmt.Printf("发送失败: %v\n", err)
//		return
//	}
//	fmt.Printf("发送成功! 消息ID: %d\n", result.Data[0].MessageId)
//}
